package com.umpay.controller.base;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.umpay.dict.XmlData;
import com.umpay.dto.UMF;
import com.umpay.dto.UMFRequest;
import com.umpay.dto.UMFResponse;
import com.umpay.dto.UMFResponse.Message;
import com.umpay.dto.UMFResponse.Message.Meta;
import com.umpay.util.SignatureAuthUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public abstract class AbstractController {

    private static final Logger log = LogManager.getLogger(AbstractController.class);

    @Autowired
    private SignatureAuthUtil signatureAuthUtil;

    /**
     * 获取响应体（无links情况）
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param map
     * @return
     */
    protected static Message getUMFResponseBody(Map<String, Object> map) {
        Message body = new Message();
        if (!CollectionUtils.isEmpty(map)) {
            String retCode = StringUtils.trim((String) map.get(UMFResponse.MESSAGE_META_RETCODE));
            String retMsg = StringUtils.trim((String) map.get(UMFResponse.MESSAGE_META_RETMSG));
            if (StringUtils.isNotEmpty(retCode) || StringUtils.isNotEmpty(retMsg)) {
                body.setMeta(new Meta(retCode, retMsg));
            }
            Object obj = map.get(UMFResponse.MESSAGE_DATA);
            body.setData(obj);
        }
        return body;
    }

    /**
     * 转换json数据
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param obj
     * @return
     */
    protected static <T> String getJsonString(Message<T> body) {
        String result = "";
        try {
            result = new ObjectMapper().writeValueAsString(body);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    /**
     * 获取签名
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param json
     * @return
     */
    protected String getSign(String json) {
        return signatureAuthUtil.signMsg(json);
    }

    /**
     * 数据响应
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param body
     * @param response
     * @return
     */
    protected <T> Message<T> responseMsg(Message<T> body, HttpServletResponse response) {
        try {
            response.setHeader(UMF.SIGN, signatureAuthUtil.signMsg(new ObjectMapper().writeValueAsString(body)));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return body;
    }

    /**
     * 数据响应
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param body
     * @param response
     * @return
     */
    protected Object responseMsg1(Object obj, HttpServletResponse response) {
        try {
            response.setHeader(UMF.SIGN, signatureAuthUtil.signMsg(new ObjectMapper().writeValueAsString(obj)));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return obj;
    }

    /**
     * 获取请求体
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param request
     * @return
     */
    protected <T> T getReqMessage(HttpServletRequest request) {
        UMFRequest<T> umfRequest = (UMFRequest<T>) request.getAttribute(UMFRequest.REQUEST);
        log.info(String.format("接受请求参数[%s]", umfRequest));
        return umfRequest.getMessage();
    }

    /**
     * 前台通知
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param message
     * @return
     * @throws Exception
     */
    protected String getAssembleFrontUrl(Message<Map<String, String>> message) throws Exception {
        Meta meta = message.getMeta();
        String retCode = meta.getRet_code();
        String retMsg = meta.getRet_msg();
        Map<String, String> reqMap = new HashMap<String, String>();
        reqMap.putAll(message.getData());
        reqMap.put("ret_code", retCode);
        reqMap.put("ret_msg", retMsg);
        reqMap.put(UMF.SIGN, signatureAuthUtil.signMsgFront(reqMap));
        return encodeUrl(reqMap);
    }

    /**
     * 编码
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param reqMap
     * @return
     * @throws Exception
     */
    private String encodeUrl(Map<String, String> reqMap) throws Exception {
        StringBuilder reqstr = new StringBuilder("");
        Set<Map.Entry<String, String>> set = reqMap.entrySet();
        Iterator<Map.Entry<String, String>> it = set.iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> item = it.next();
            String key = item.getKey();
            String value = item.getValue();
            if (!key.equalsIgnoreCase(XmlData.PLAIN)) { // 商户请求的参数如果为空，不传递给后台，并且sign和plain字段不参与数据组装给后台
                value = StringUtils.trim(reqMap.get(key)); // 获得非空请求字段值
                if (StringUtils.isNotEmpty(value)) {
                    value = URLEncoder.encode(value.replaceAll("\\+", "%2B"), "UTF-8");
                    reqstr.append(key).append("=").append(value).append("&");
                }
            }
        }
        String url = reqstr.substring(0, reqstr.length() - 1); // 截取明文串(最后一位多个"&"符号)
        log.debug(String.format("商户请求数据组装字符串结果为：%s", url));
        return url;
    }
}
